﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace Easycmd
{
    /// <summary>
    /// DataSet format:    
    /// easycmd{lastgroup=} ,
    ///     group{group_id,name,easycmd_id},
    ///     left{left_id,group_id},right{rightid,groupid},
    ///         dir{left_id,right_id,dir_text}
    /// </summary>
    public class XMLConf
    {
        string xmlfile = "";
        DataSet ds;
        public XMLConf(string file)
        {
            xmlfile = file;
            ds = new DataSet();
            try
            {
                ds.ReadXml(xmlfile);
            }catch{}
        }
        public string getLastOpenGroupName()
        {
            DataTable dt = ds.Tables["easycmd"];
            return dt.Rows[0]["lastgroup"].ToString();
        }
        IList<string> lefts = new List<string>();
        IList<string> rights = new List<string>();
        public IList<string> getLefts()
        {
            Init();
            return lefts;
        }

        private void Init()
        {
            if (lefts.Count == 0 && rights.Count == 0)
            {
                DataTable dt = ds.Tables["dir"];
                foreach (DataRow row in dt.Rows)
                {
                    if (dt.Columns.Contains("left_id") &&
                        row["left_id"].GetType() != typeof(System.DBNull) &&
                        LeftIdInGroup(Convert.ToInt32(row["left_id"]), getLastOpenGroupName(), ds))
                    {
                        lefts.Add(row["dir_text"].ToString());
                    }
                    else if (dt.Columns.Contains("right_id") &&
                        row["right_id"].GetType() != typeof(System.DBNull) &&
                        RightIdInGroup(Convert.ToInt32(row["right_id"]), getLastOpenGroupName(), ds))
                    {
                        rights.Add(row["dir_text"].ToString());
                    }
                }
            }
        }
        private bool RightIdInGroup(int rightid, string groupname, DataSet ds)
        {
            DataTable group_t = ds.Tables["group"];
            int groupid = 0;
            foreach (DataRow group_row in group_t.Rows)
            {
                if (group_row["name"].ToString() == groupname)
                    groupid = Convert.ToInt32(group_row["group_id"]);
            }
            DataTable dt = ds.Tables["right"];
            foreach (DataRow row in dt.Rows)
            {
                if (Convert.ToInt32(row["group_id"]) == groupid && Convert.ToInt32(row["right_id"]) == rightid) return true;
            }
            return false;
        }

        private bool LeftIdInGroup(int leftid, string groupname, DataSet ds)
        {
            DataTable group_t = ds.Tables["group"];
            int groupid = 0;
            foreach (DataRow group_row in group_t.Rows)
            {
                if (group_row["name"].ToString() == groupname)
                    groupid = Convert.ToInt32(group_row["group_id"]);
            }

            DataTable dt = ds.Tables["left"];
            foreach (DataRow row in dt.Rows)
            {
                if (Convert.ToInt32(row["group_id"]) == groupid && Convert.ToInt32(row["left_id"]) == leftid) return true;
            }
            return false;
        }
        public IList<string> getRights()
        {
            Init();
            return rights;
        }
        internal void WriteLefts(IList<string> newlefts, string groupName)
        {
            DataTable dt = ds.Tables["dir"];
            ClearLeftOfGroup(groupName);
            foreach (string dir in newlefts)
            {
                DataRow r = dt.Rows.Add();
                r["left_id"] = getGroupIdFromName(groupName);
                r["dir_text"] = dir;
                //dt.Rows.Add(r);
            }            
        }
        /// <summary>
        /// 清除指定groupName的Left 行
        /// </summary>
        /// <param name="groupName"></param>
        /// <param name="dt"></param>
        private void ClearLeftOfGroup(string groupName)
        {
            DataTable dt = ds.Tables["dir"];
            IList<DataRow> rows = new List<DataRow>();
            foreach (DataRow row in dt.Rows)
            {
                if (row["right_id"].GetType() == typeof(DBNull) &&
                    GroupIdOfLeftId(Convert.ToInt32(row["left_id"])) == getGroupIdFromName(groupName))
                    rows.Add(row);
            }
            foreach (DataRow row in rows)
            {
                dt.Rows.Remove(row);
            }
        }

        private int GroupIdOfLeftId(int id)
        {
            DataTable left = ds.Tables["left"];
            foreach (DataRow row in left.Rows)
            {
                if (Convert.ToInt32(row["left_id"]) == id)
                    return Convert.ToInt32(row["group_id"]);
            }
            return 0;
        }
        internal void WriteLefts(IList<string> newlefts)
        {
            WriteLefts(newlefts, "default");
        }

        internal int getLastOpenGroupId()
        {
            return getGroupIdFromName(getLastOpenGroupName());
        }
        internal int getGroupIdFromName(string groupName)
        {
            DataTable dt = ds.Tables["group"];
            foreach (DataRow row in dt.Rows)
            {
                if (row["name"].ToString() == groupName)
                    return Convert.ToInt32(row["group_id"]);
            }
            return 0;
        }

        internal void Save()
        {
            ds.WriteXml(xmlfile);
        }

        internal void WriteRights(IList<string> ss)
        {
            WriteRights(ss, "default");
        }
        internal void WriteRights(IList<string> newRights, string groupName)
        {
            DataTable dt = ds.Tables["dir"];
            ClearRightOfGroup(groupName);
            foreach (string dir in newRights)
            {
                DataRow r = dt.Rows.Add();
                r["right_id"] = getGroupIdFromName(groupName);
                r["dir_text"] = dir;
                //dt.Rows.Add(r);
            }
        }
        /// <summary>
        /// 清除指定groupName的Right 行
        /// </summary>
        /// <param name="groupName"></param>
        /// <param name="dt"></param>
        private void ClearRightOfGroup(string groupName)
        {
            DataTable dt = ds.Tables["dir"];
            IList<DataRow> rows = new List<DataRow>();
            foreach (DataRow row in dt.Rows)
            {
                if (dt.Columns.Contains("right_id")&&
                    row["right_id"].GetType()!=typeof(DBNull)&&
                    GroupIdOfRightId(Convert.ToInt32(row["right_id"])) == getGroupIdFromName(groupName))
                    rows.Add(row);
            }
            foreach (DataRow row in rows)
            {
                dt.Rows.Remove(row);
            }
        }

        private int GroupIdOfRightId(int id)
        {
            DataTable left = ds.Tables["right"];
            foreach (DataRow row in left.Rows)
            {
                if (Convert.ToInt32(row["right_id"]) == id)
                    return Convert.ToInt32(row["group_id"]);
            }
            return 0;
        }

        internal IList<string> Groups()
        {
            IList<string> r = new List<string>();
            DataTable dt = ds.Tables["group"];
            foreach (DataRow row in dt.Rows)
            {
                r.Add(row["name"].ToString());
            }
            return r;
        }

        internal void SetDefaultGroup(string p)
        {
             DataTable dt = ds.Tables["easycmd"];
             dt.Rows[0]["lastgroup"] = p;
        }
    }
    class Testcase
    {
        static void Test_getLastOpenGroupId()
        {
            XMLConf conf = new XMLConf(XML_FILE_NAME);
            Console.WriteLine(conf.getLastOpenGroupId());
            Console.WriteLine(conf.getGroupIdFromName("dev"));
            Console.WriteLine(conf.getGroupIdFromName("default"));
        }
        static void WriteLefts()
        {
            XMLConf conf = new XMLConf(XML_FILE_NAME);
            IList<string> newlefts = new  List<string>();
            foreach(string dir in conf.getLefts()){
                newlefts.Add(dir);
            }
            //add one d:\windows
            newlefts.Add(@"d:\windows");
            newlefts.Add(@"d:\windows\system32");
            conf.WriteLefts( newlefts);
            conf.Save();
            // show it 
            conf = new XMLConf("new.xml");
            foreach (string dir in conf.getLefts())
            {
                Console.WriteLine(dir);
            }
        }
        static void WriteRight()
        {
            XMLConf conf = new XMLConf(XML_FILE_NAME);
            IList<string> newrights = new List<string>();
            foreach (string dir in conf.getRights())
            {
                newrights.Add(dir);
            }
            //add one d:\windows
            newrights.Add(@"d:\windows");
            newrights.Add(@"d:\windows\system32");
            conf.WriteRights(newrights);
            conf.Save();
            // show it 
            conf = new XMLConf(XML_FILE_NAME);
            foreach (string dir in conf.getRights())
            {
                Console.WriteLine(dir);
            }
        }
        static void testLastOpenGroup()
        {
            XMLConf conf = new XMLConf(XML_FILE_NAME);
            Console.WriteLine(conf.getLastOpenGroupName());
        }
        static string XML_FILE_NAME = "xmlfile1.xml";
        static void testLastOpenLeft()
        {
            XMLConf conf = new XMLConf(XML_FILE_NAME);
            foreach (string str in conf.getRights())
            {
                Console.WriteLine(str);
            }
            Console.WriteLine("lefts:");
            foreach (string str in conf.getLefts())
            {
                Console.WriteLine(str);
            }
        }
        static void printAllGroups()
        {
            XMLConf c = new XMLConf (XML_FILE_NAME);
            IList <string> gs = c.Groups();
            foreach (string g in gs)
            {
                Console.WriteLine(g);
            }            
        }
        static void SetDefaultGroup()
        {
            XMLConf c = new XMLConf(XML_FILE_NAME);
            c.SetDefaultGroup("default");
            c.Save();
        }
    }
}
